/* nLayers (c) 
 * Created on Jan 29, 2004
 */
package dnl.util.ui.table.sort;

import ajul.lang.EqualsUtil;
import ajul.lang.HashCodeUtil;


/**
 * 
 * 
 * @author <a href="mailto:daniel@nlayers.com">Daniel Or</a>
 */
public final class SortBy  { 

  /**
  * @param aSortOrder satisfies <code>aSortOrder!=null</code> and denotes ascending 
  * or descending order.
  * @param aColumn satisfies <code>aColumn >= 0</code> and is the index of a 
  * table column.
  */
  public SortBy (
    SortDirection aSortOrder,
    int aColumn
    ) {
    
    fSortOrder = aSortOrder;
    fColumn = aColumn;
    
    validateState();
  }

  /**
  * Return the sense of the sort, either ascending or descending.
  */
  public SortDirection getOrder() {
    return fSortOrder;
  }
  
  /**
  * Return the column index identifying the sort, or {@link #NO_SELECTED_COLUMN}
  * in the case of {@link #NONE}. 
  */
  public int getColumn() {
    return fColumn;
  }
  
  /**
  * A special <code>SortBy</code> which represents the absence of any sort.
  */
  public static final SortBy NONE = new SortBy();
  
  /**
  * The special value of the column index used by {@link #NONE}. 
  */
  public static final int NO_SELECTED_COLUMN = -1;

  /**
  * Represent this object as a <code>String</code> - intended 
  * for debugging purposes only.
  */
  @Override
public String toString() {
    StringBuffer result = new StringBuffer();
    String newLine = System.getProperty("line.separator");
    result.append( this.getClass().getName() );
    result.append(" {");
    result.append(newLine);

    result.append(" fSortOrder = ").append(fSortOrder).append(newLine);
    result.append(" fColumn = ").append(fColumn).append(newLine);
    
    result.append("}");
    result.append(newLine);
    return result.toString();
  }

  @Override
  public boolean equals( Object aThat ) {
    if ( this == aThat ) return true;
    if ( !(aThat instanceof SortBy) ) return false;
    SortBy that = (SortBy)aThat;
    return 
      EqualsUtil.areEqual(this.fSortOrder, that.fSortOrder) &&
      EqualsUtil.areEqual(this.fColumn, that.fColumn);
  }

  @Override
  public int hashCode() {
    int result = HashCodeUtil.SEED;
    result = HashCodeUtil.hash( result, fSortOrder );
    result = HashCodeUtil.hash( result, fColumn );
    
    return result;
  }

  // PRIVATE // 
  private final SortDirection fSortOrder;
  private final int fColumn;
  
  private void validateState() {
    boolean hasValidState = 
      ( fSortOrder!=null ) &&
      ( fColumn >= 0 ) ;
    if ( !hasValidState ) throw new IllegalArgumentException(this.toString());
  }
  
  /**
  * Constructor used only for the special case of no sort at all.
  *
  * Note that this constructor does not perform the validations done by the public 
  * constructor, and is thus not subject to the same restrictions.
  */
  private SortBy(){
    fSortOrder = SortDirection.Descending;
    fColumn = NO_SELECTED_COLUMN;
  }
} 
